package inst.ejb.utilities;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.sql.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.persistence.EntityManager;
import javax.persistence.EntityNotFoundException;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.hibernate.exception.ConstraintViolationException;

public class BaseSessionBean<T> extends LookupLocal implements BaseDao<T> {
	// unitname is pre-defined in persistence.xml
	/**
	 * @uml.property name="em"
	 * @uml.associationEnd readOnly="true" multiplicity="(0 -1)"
	 *                     elementType="xinstru.sysman.logic.entitybeans.CommonCode"
	 */
	@PersistenceContext(unitName = "inst")
	protected EntityManager em;

	/**
	 * @uml.property name="entityClass"
	 */
	private final Class<T> entityClass;

	public BaseSessionBean() {
		super();
		// TODO Auto-generated constructor stub
		entityClass = (Class<T>) ((ParameterizedType) getClass()
				.getGenericSuperclass()).getActualTypeArguments()[0];
		Log.debug("Entity Class is : " + entityClass.getName());

	}

	/**
	 * 
	 */

	public PagedResults<T> findAnyFieldsContaints(String ownerid, String value,
			Integer containsType, PageInfo pageInfo) {
		Log.debug("find ....");
		String eql = "from ViewOrgInfo "; // + entityClass.getSimpleName();
		Field[] fields = entityClass.getDeclaredFields();

		String whereSql = "";

		Map<String, Object> params = new HashMap<String, Object>();
		params.put("ownerid", ownerid + "%");
		for (Field f : fields) {
			if ("ownerid".equalsIgnoreCase(f.getName())) {
				continue;
			}
			Log.debug(f.getName() + " type is :" + f.getType().toString());
			if (f.getType().equals(String.class)) {
				switch (containsType) {
				case Constants.CONTAIN_TYPE_START_WITH: // start with
					params.put(f.getName(), value + "%");
					break;
				case Constants.CONTAIN_TYPE_END_WITH: // end with
					params.put(f.getName(), "%" + value);
					break;
				case Constants.CONTAIN_TYPE_CONTAINS: // any where contains;
					params.put(f.getName(), "%" + value + "%");
					break;
				default:
					params.put(f.getName(), "%" + value + "%");
					break;
				}
				whereSql += " or " + f.getName() + " like :" + f.getName();
			}
		}
		whereSql = " where ownerid like :ownerid and orgTypeFlag < 9 and status<99 and ("
				+ whereSql.substring(4) + ")";

		Query cntQry = em.createQuery("select count(*) " + eql + whereSql);
		Query query = em.createQuery(eql + whereSql);

		Log.debug(eql + whereSql);

		String key = "";
		Iterator<String> keys = params.keySet().iterator();
		while (keys.hasNext()) {
			key = keys.next().toString();
			query.setParameter(key, params.get(key));
			cntQry.setParameter(key, params.get(key));
			Log.debug(key + " = " + params.get(key));
		}
		Integer cnt = Integer.parseInt(cntQry.getSingleResult().toString());
		pageInfo.setRecordCount(cnt);
		return findListByQuery(query, pageInfo);

	}

	public T findByPk(Object id) {
		Log.debug(entityClass.toString());
		if (em == null) {
			Log.error("EntityManager is null");
		}
		try {
			return em.find(entityClass, id);

		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
		return null;
	}

	@TransactionAttribute(TransactionAttributeType.REQUIRED)
	public void remove(Object o) {
		// TODO Auto-generated method stub
		String errorMsg = null;
		try {
			o = em.merge(o);
			em.remove(o);
		} catch (EntityNotFoundException e) {
			e.printStackTrace();
		} catch (Exception e) {
			// TODO: handle exception
			Throwable t = e.getCause();
			do {
				Log.debug(t.getClass().toString());
				Log.debug(t.toString());
				errorMsg += t.toString() + "\n";
				t = t.getCause();
			} while (t != null);
		}
	}

	public void removeByPk(Object id) {
		// TODO Auto-generated method stub
		try {
			Object obj = em.find(entityClass, id);
			em.remove(obj);
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}

	public Object initializeDefaultValue(Object o, Object defaultValue) {
		Field[] fields = o.getClass().getDeclaredFields();
		String getMethodName = "";
		String setMethodName = "";
		Method method;
		Object rtn;
		for (Field f : fields) {
			if (!"id".equalsIgnoreCase(f.getName())) {
				getMethodName = "get"
						+ f.getName().substring(0, 1).toUpperCase()
						+ f.getName().substring(1);
				setMethodName = "set"
						+ f.getName().substring(0, 1).toUpperCase()
						+ f.getName().substring(1);
				try {
					method = o.getClass().getMethod(getMethodName, null);
					rtn = method.invoke(o, null);

					if (rtn == null) {
						if (f.getType().equals(Integer.class)) {
							method = o.getClass().getMethod(setMethodName,
									Integer.class);
							method.invoke(o, 0);
						}

						if (f.getType().equals(Boolean.class)) {
							method = o.getClass().getMethod(setMethodName,
									Boolean.class);
							method.invoke(o, false);
						}

						if (f.getType().equals(int.class)) {
							method = o.getClass().getMethod(setMethodName,
									int.class);
							method.invoke(o, 0);
						}
						if (f.getType().equals(Long.class)) {
							method = o.getClass().getMethod(setMethodName,
									Long.class);
							method.invoke(o, 0l);
						}

						if (f.getType().equals(float.class)) {
							method = o.getClass().getMethod(setMethodName,
									float.class);
							method.invoke(o, 0f);
						}
						if (f.getType().equals(Double.class)) {
							method = o.getClass().getMethod(setMethodName,
									Double.class);
							method.invoke(o, 0.0);
						}
						if (f.getType().equals(String.class)) {
							method = o.getClass().getMethod(setMethodName,
									String.class);
							method.invoke(o, defaultValue);
						}
					}
				} catch (SecurityException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (NoSuchMethodException e) {
					// TODO Auto-generated catch block
					Log.debug("the following method not found at "
							+ o.getClass().getName());
					Log.debug(getMethodName);
					Log.debug(setMethodName);

					// e.printStackTrace();
				} catch (IllegalArgumentException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (InvocationTargetException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

			}
		}
		return o;
	}

	public T save(Object o) {
		// TODO Auto-generated method stub
		try {
			//
			o = initializeDefaultValue(o, null);
			o = em.merge(o);
			em.persist(o);
			em.flush();
			return (T) o;
		} catch (ConstraintViolationException e) {
			Log.debug(e.getSQLException().getMessage());
			e.printStackTrace();
			// throw new AppException(e.getSQLException().getMessage());
		} catch (Exception e) {
			String errorMsg = "";
			// TODO: handle exception
			Log.debug(e.getClass().toString());
			Throwable t = e.getCause();
			do {
				Log.debug(t.getClass().toString());
				Log.debug(t.toString());
				errorMsg += t.toString() + "\n";
				t = t.getCause();
			} while (t != null);
			Log.debug("error Message ...................................");
			Log.debug(errorMsg);
			e.printStackTrace();
			// throw new Exception(errorMsg);
		}
		return null;
	}
	public T bigSave(Object o)throws Exception{
		try {
			o = initializeDefaultValue(o, null);
			o = em.merge(o);
			em.persist(o);
			//em.flush();
			return (T) o;
		} catch (ConstraintViolationException e) {
			Log.debug(e.getSQLException().getMessage());
			e.printStackTrace();
			throw new AppException(e.getSQLException().getMessage());
		} catch (Exception e) {
			String errorMsg = "";
			// TODO: handle exception
			Log.debug(e.getClass().toString());
			Throwable t = e.getCause();
			do {
				Log.debug(t.getClass().toString());
				Log.debug(t.toString());
				errorMsg += t.toString() + "\n";
				t = t.getCause();
			} while (t != null);
			Log.debug("error Message ...................................");
			Log.debug(errorMsg);
			e.printStackTrace();
			throw new Exception(errorMsg);
		}
	}
	/**
	 * 保存数据到数据库
	 * @param o
	 * @throws Exception
	 */
	public T saveExcep(Object o)throws Exception{
		try {
			//
			o = initializeDefaultValue(o, null);
			o = em.merge(o);
			em.persist(o);
			em.flush();
			return (T) o;
		} catch (ConstraintViolationException e) {
			Log.debug(e.getSQLException().getMessage());
			e.printStackTrace();
			throw new AppException(e.getSQLException().getMessage());
		} catch (Exception e) {
			String errorMsg = "";
			// TODO: handle exception
			Log.debug(e.getClass().toString());
			Throwable t = e.getCause();
			do {
				Log.debug(t.getClass().toString());
				Log.debug(t.toString());
				errorMsg += t.toString() + "\n";
				t = t.getCause();
			} while (t != null);
			Log.debug("error Message ...................................");
			Log.debug(errorMsg);
			e.printStackTrace();
			throw new Exception(errorMsg);
		}
	}
	public List<T> findListByQuery(Query query) {
		return query.getResultList();
	}
	public List findListObjByQuery(Query query) {
		return query.getResultList();
	}
	public PageInfo initialPageInfo(int totalResult) {
		PageInfo rslt = new PageInfo();
		rslt.setFirstResult(0);
		rslt.setPageIndex(1);
		rslt.setPageSize(20);
		int pageTotal = 0;
		pageTotal = totalResult % rslt.getPageSize() > 0 ? totalResult
				/ rslt.getPageSize() + 1 : totalResult / rslt.getPageSize();
		rslt.setPageTotal(pageTotal);
		rslt.setRecordCount(totalResult);
		return rslt;
	}

	public PagedResults<T> findListByQuery(Query query, PageInfo pageInfo) {
		// TODO Auto-generated method stub
		PagedResults<T> result = new PagedResults<T>();
		if (pageInfo != null && pageInfo.getPageSize() != -2) {
			if (pageInfo.getPageIndex()==null||pageInfo.getPageIndex() <= 0) {
				pageInfo.setPageIndex(1);
				pageInfo.setFirstResult(0);
			}
			pageInfo.setFirstResult((pageInfo.getPageIndex() - 1)
					* pageInfo.getPageSize());

			int first = pageInfo.getFirstResult() < 0 ? 0 : pageInfo
					.getFirstResult();
			int max = pageInfo.getPageSize();
			query.setFirstResult(first);
			query.setMaxResults(max);
			result.setResultList(query.getResultList());

			int pageTotal = 0;
			pageTotal = pageInfo.getRecordCount() % pageInfo.getPageSize() > 0 ? pageInfo
					.getRecordCount()
					/ pageInfo.getPageSize() + 1
					: pageInfo.getRecordCount() / pageInfo.getPageSize();

			pageInfo.setPageTotal(pageTotal);
			int pageIndex = pageInfo.getPageIndex() > pageTotal ? pageTotal
					: pageInfo.getPageIndex();

			pageInfo.setPageIndex(pageIndex);
			Log.debug("record Count =" + pageInfo.getRecordCount()
					+ "\npage total =" + pageInfo.getPageTotal()
					+ "\npage Size =" + pageInfo.getPageSize()
					+ "\npage Index=" + pageInfo.getPageIndex());
		} else {
			result.setResultList(findListByQuery(query));
		}
		result.setPageInfo(pageInfo);
		return result;
	}
	public PagedResults<Object> findListObjectByQuery(Query query, PageInfo pageInfo) {
		// TODO Auto-generated method stub
		PagedResults<Object> result = new PagedResults<Object>();
		if (pageInfo != null && pageInfo.getPageSize() != -2) {
			if (pageInfo.getPageIndex()==null||pageInfo.getPageIndex() <= 0) {
				pageInfo.setPageIndex(1);
				pageInfo.setFirstResult(0);
			}
			pageInfo.setFirstResult((pageInfo.getPageIndex() - 1)
					* pageInfo.getPageSize());

			int first = pageInfo.getFirstResult() < 0 ? 0 : pageInfo
					.getFirstResult();
			int max = pageInfo.getPageSize();
			query.setFirstResult(first);
			query.setMaxResults(max);
			result.setResultList(query.getResultList());

			int pageTotal = 0;
			pageTotal = pageInfo.getRecordCount() % pageInfo.getPageSize() > 0 ? pageInfo
					.getRecordCount()
					/ pageInfo.getPageSize() + 1
					: pageInfo.getRecordCount() / pageInfo.getPageSize();

			pageInfo.setPageTotal(pageTotal);
			int pageIndex = pageInfo.getPageIndex() > pageTotal ? pageTotal
					: pageInfo.getPageIndex();

			pageInfo.setPageIndex(pageIndex);
			Log.debug("record Count =" + pageInfo.getRecordCount()
					+ "\npage total =" + pageInfo.getPageTotal()
					+ "\npage Size =" + pageInfo.getPageSize()
					+ "\npage Index=" + pageInfo.getPageIndex());
		} else {
			result.setResultList(findListObjByQuery(query));
		}
		result.setPageInfo(pageInfo);
		return result;
	}
	/*
	 * findByPage without parameters;
	 */
	public PagedResults<T> findByPage(String ejbql, PageInfo pageInfo) {
		return findListByEJBQL(ejbql, pageInfo, null);
	}

	@SuppressWarnings("unchecked")
	public PagedResults<T> findListByEJBQL(String ejbql, PageInfo pageInfo,
			Map parameters) {
		Log.debug(entityClass.getSimpleName());
		if ((ejbql == null) || ("".equals(ejbql))) {
			ejbql = "from " + entityClass.getSimpleName();
		}
		Log.debug(ejbql);

		try {
			new PagedResults<T>();
			Query query;
			Iterator keys = null;

			if (parameters != null) {
				keys = parameters.keySet().iterator();
			}
			String key = null;

			if ((pageInfo != null) && (pageInfo.getFirstResult() <= 0)) {

				String cntSql = "select count(*) "
						+ ejbql.substring(ejbql.indexOf("from "));
				if (cntSql.toLowerCase().contains(" group by ")) {
					cntSql = cntSql.substring(0, cntSql.toLowerCase().indexOf(
							" group by"));
				}
				if (cntSql.toLowerCase().contains(" order by ")) {
					cntSql = cntSql.substring(0, cntSql.toLowerCase().indexOf(
							" order by"));
				}

				Log.debug(cntSql);
				query = em.createQuery(cntSql);

				while ((keys != null) && (keys.hasNext())) {
					key = keys.next().toString();
					Log.debug("key = " + key + "\n value="
							+ parameters.get(key));
					if (ejbql.contains(":" + key)) {
						query.setParameter(key, parameters.get(key));
					}
				}

				pageInfo.setRecordCount(Integer.parseInt(query
						.getSingleResult().toString()));
			}

			if (parameters != null) {
				keys = parameters.keySet().iterator();
			}

			query = em.createQuery(ejbql);
			while ((keys != null) && (keys.hasNext())) {
				key = keys.next().toString();
				Log.debug("key = " + key + "/ value=" + parameters.get(key));
				if (ejbql.contains(":" + key)) {
					query.setParameter(key, parameters.get(key));
				}
			}
			return findListByQuery(query, pageInfo);

		} catch (Exception e) {
			// TODO: handle exception
			Log.error(e.getMessage());
			return null;
		}
	}

	public PagedResults<T> findList(Object enquiryParamObject,
			PageInfo pageInfo, Boolean includeDeleted) {
		String ejbql = "";
		Field[] fields = enquiryParamObject.getClass().getDeclaredFields();
		Method method;
		String methodName;
		for (Field f : fields) {
			Log.debug("Property Name = " + f.getName());
			methodName = "get" + f.getName().substring(0, 1).toUpperCase()
					+ f.getName().substring(1);
			Log.debug("methodName is " + methodName);
			try {
				method = enquiryParamObject.getClass().getMethod(methodName,
						null);
				Log.debug("method return type :"
						+ method.getReturnType().getSimpleName());
				Object v = method.invoke(enquiryParamObject, null);
				if (v != null && !"".equals(v.toString())) {
					Log.debug(f.getName() + "=" + v.toString());
					if (method.getReturnType().equals(String.class)) {
						ejbql += " and " + f.getName() + " like '%"
								+ v.toString() + "%'";
					}
					if (method.getReturnType().equals(Integer.class)
							|| method.getReturnType().equals(Date.class)
							|| method.getReturnType().equals(Short.class)
							|| method.getReturnType().equals(int.class)
							|| method.getReturnType().equals(short.class)) {
						ejbql += " and " + f.getName() + "=" + v.toString();
					}
				}
			} catch (SecurityException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (NoSuchMethodException e) {
				// TODO Auto-generated catch block
				Log.error(methodName + " not found");
				// e.printStackTrace();
			} catch (IllegalArgumentException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		/*
		 * 如果不包含已经删除的数据，并且对象中在STATUS字段�?则设置STATUS < 99;
		 */
		if (ejbql.trim().startsWith("and ")) {
			ejbql = ejbql.substring(4);
		}
		if (!includeDeleted) {
			fields = entityClass.getDeclaredFields();
			for (Field f : fields) {
				if ("status".equalsIgnoreCase(f.getName())) {
					ejbql = " status < 99 and " + ejbql;
					break;
				}
			}
		}
		if (ejbql.trim().toLowerCase().endsWith(" and")) {
			ejbql = ejbql.substring(0, ejbql.length() - 3);
		}
		if (ejbql.trim().toLowerCase().startsWith("and ")) {
			ejbql = ejbql.substring(5);
		}

		if (!"".equals(ejbql)) {
			ejbql = " where " + ejbql;
		}
		ejbql = "from " + entityClass.getSimpleName() + ejbql;
		Log.debug(ejbql);

		if ((ejbql.indexOf(" order by ") <= 0) && (fieldExists("idx"))) {
			ejbql = ejbql + " order by idx";
		}
		return findListByEJBQL(ejbql, pageInfo, null);
	}

	public PagedResults<T> findListWithIn(Object enquiryParamObject,
			String appendSql, PageInfo pageInfo, Boolean includeDeleted) {
		String ejbql = "";
		Field[] fields = enquiryParamObject.getClass().getDeclaredFields();
		Method method;
		String methodName;
		for (Field f : fields) {
			Log.debug("Property Name = " + f.getName());
			methodName = "get" + f.getName().substring(0, 1).toUpperCase()
					+ f.getName().substring(1);
			Log.debug("methodName is " + methodName);
			try {
				method = enquiryParamObject.getClass().getMethod(methodName,
						null);
				Log.debug("method return type :"
						+ method.getReturnType().getSimpleName());
				Object v = method.invoke(enquiryParamObject, null);
				if (v != null && !"".equals(v.toString())) {
					Log.debug(f.getName() + "=" + v.toString());
					if (method.getReturnType().equals(String.class)) {
						ejbql += " and " + f.getName() + " like '%"
								+ v.toString() + "%'";
					}
					if (method.getReturnType().equals(Integer.class)
							|| method.getReturnType().equals(Date.class)
							|| method.getReturnType().equals(Short.class)
							|| method.getReturnType().equals(int.class)
							|| method.getReturnType().equals(short.class)) {
						// System.out.println(f.getName());

						if (f.getName() != null
								&& f.getName().equals("authState")) {
							if (v.toString().equals("1")) {
								ejbql += " and " + "authTotal" + "<"
										+ "infactTotal";
							} else if (v.toString().equals("-1")) {
								// ejbql += " and " + f.getName() + "<" +
								// v.toString();
								ejbql += " and " + "authTotal" + ">"
										+ "infactTotal";
							} else {
								ejbql += " and " + "authTotal" + "="
										+ "infactTotal";
							}
						} else if (f.getName() != null
								&& f.getName().equals("orgTypeFlag")) {
							if (v.toString().equals("14")) {
								ejbql += " and " + f.getName() + " in('1','4')";
							} else if (v.toString().equals("0")) {

							}/*
							 * else if (v.toString().equals("1")) { ejbql +=
							 * " and " + f.getName() + "=" +
							 * v.toString()+" and org_Class not in('街道','�?,'�?)"
							 * ; }
							 */
							else {
								ejbql += " and " + f.getName() + "="
										+ v.toString();
							}

						} else {
							ejbql += " and " + f.getName() + "=" + v.toString();
						}
					}
				}

				// System.out.println(ejbql);
			} catch (SecurityException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (NoSuchMethodException e) {
				// TODO Auto-generated catch block
				Log.error(methodName + " not found");
				// e.printStackTrace();
			} catch (IllegalArgumentException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		/*
		 * 如果不包含已经删除的数据，并且对象中在STATUS字段�?则设置STATUS < 99;
		 */
		if (ejbql.trim().startsWith("and ")) {
			ejbql = ejbql.substring(4);
		}
		if (!includeDeleted) {
			fields = entityClass.getDeclaredFields();
			for (Field f : fields) {
				if ("status".equalsIgnoreCase(f.getName())) {
					ejbql = " status < 99 and " + ejbql;
					break;
				}
			}
		}
		if (ejbql.trim().toLowerCase().endsWith(" and")) {
			ejbql = ejbql.substring(0, ejbql.length() - 3);
		}
		if (ejbql.trim().toLowerCase().startsWith("and ")) {
			ejbql = ejbql.substring(5);
		}

		if (!"".equals(ejbql)) {
			ejbql = " where " + ejbql;
		}
		ejbql = "from " + entityClass.getSimpleName() + ejbql;

		// ..
		if (appendSql != null && !appendSql.equals("")) {
			ejbql += appendSql;
		}
		ejbql += " and orgTypeFlag <> 9";
		Log.debug(ejbql);

		if ((ejbql.indexOf(" order by ") <= 0) && (fieldExists("idx"))) {
			ejbql = ejbql + " order by idx";
		}

		PagedResults<T> res = findListByEJBQL(ejbql, pageInfo, null);
		// 合计数据
		//String cntSql = "select count (*) as cnt ,sum(authTotal),sum(auth1+auth2),sum(infactTotal),sum(infact1+infact2)"
		//		+ ejbql.substring(ejbql.indexOf("from "), ejbql
		//				.indexOf("order by "));
		//Query qry = this.createQuery(cntSql);
		//Object[] o = (Object[]) qry.getSingleResult();
		//res.setCntRes(o);

		return res;
	}

	private boolean fieldExists(String fieldName) {
		Field[] fields = entityClass.getDeclaredFields();
		for (Field f : fields) {
			if (fieldName.equalsIgnoreCase(f.getName())) {
				return true;
			}
		}
		return false;
	}

	public PagedResults<T> findList(String EJBQL, Object enquiryParamObject,
			PageInfo pageInfo) {
		Query query = em.createQuery(EJBQL);
		Field[] fields = enquiryParamObject.getClass().getDeclaredFields();
		Method method;
		String methodName;
		for (Field f : fields) {
			Log.debug("Property Name = " + f.getName());
			methodName = "get" + f.getName().substring(0, 1).toUpperCase()
					+ f.getName().substring(1);
			Log.debug("methodName is " + methodName);
			try {
				method = enquiryParamObject.getClass().getMethod(methodName,
						null);
				Log.debug("method return type :"
						+ method.getReturnType().getSimpleName());
				Object v = method.invoke(enquiryParamObject, null);
				if (v != null && !"".equals(v.toString())) {
					query.setParameter(f.getName(), v);
				}
			} catch (Exception e) {
				// TODO: handle exception
			}
		}
		PagedResults<T> result = new PagedResults<T>();
		result.setPageInfo(pageInfo);
		result.setResultList(query.setFirstResult(pageInfo.getFirstResult())
				.setMaxResults(pageInfo.getPageSize()).getResultList());
		return result;
	}

	public PagedResults<T> findList(Object enquiryParamObject, PageInfo pageInfo) {
		// TODO Auto-generated method stub
		return findList(enquiryParamObject, pageInfo, false);
	}

	public List<T> findListByNativeSQL(String nativeSQL) {
		return em.createNativeQuery(nativeSQL).getResultList();
	}

	@Override
	public PagedResults<T> findByPageNativeSQL(String nativeSQL,
			PageInfo pageInfo, Map parameters) {
		// TODO Auto-generated method stub
		try {
			new PagedResults<T>();
			Query query;
			Iterator keys = null;

			if (parameters != null) {
				keys = parameters.keySet().iterator();
			}
			String key = null;

			if (pageInfo.getFirstResult() <= 0) {

				String cntSql = "select count(*) "
						+ nativeSQL.substring(nativeSQL.indexOf("from "));
				if (cntSql.toLowerCase().contains(" group by ")) {
					cntSql = cntSql.substring(0, cntSql.toLowerCase().indexOf(
							" group by"));
				}
				if (cntSql.toLowerCase().contains(" order by ")) {
					cntSql = cntSql.substring(0, cntSql.toLowerCase().indexOf(
							" order by"));
				}

				Log.debug(cntSql);
				query = em.createNativeQuery(cntSql);

				while ((keys != null) && (keys.hasNext())) {
					key = keys.next().toString();
					Log.debug("key = " + key + "\n value="
							+ parameters.get(key));
					query.setParameter(key, parameters.get(key));
				}

				pageInfo.setRecordCount(Integer.parseInt(query
						.getSingleResult().toString()));
			}

			if (parameters != null) {
				keys = parameters.keySet().iterator();
			}

			query = em.createNativeQuery(nativeSQL);
			while ((keys != null) && (keys.hasNext())) {
				key = keys.next().toString();
				Log.debug("key = " + key + "\n value=" + parameters.get(key));
				query.setParameter(key, parameters.get(key));
			}

			return findListByQuery(query, pageInfo);

		} catch (Exception e) {
			// TODO: handle exception
			Log.error(e.getMessage());
			return null;
		}
	}
	public PagedResults<Object> findPageObjNativeSQL(String nativeSQL,
			PageInfo pageInfo, Map parameters) {
		// TODO Auto-generated method stub
		try {
			new PagedResults<T>();
			Query query;
			Iterator keys = null;

			if (parameters != null) {
				keys = parameters.keySet().iterator();
			}
			String key = null;

			if (pageInfo.getFirstResult() <= 0) {

				String cntSql = "select count(*) "
						+ nativeSQL.substring(nativeSQL.indexOf("from "));
				if (cntSql.toLowerCase().contains(" group by ")) {
					cntSql = cntSql.substring(0, cntSql.toLowerCase().indexOf(
							" group by"));
				}
				if (cntSql.toLowerCase().contains(" order by ")) {
					cntSql = cntSql.substring(0, cntSql.toLowerCase().indexOf(
							" order by"));
				}

				Log.debug(cntSql);
				query = em.createNativeQuery(cntSql);

				while ((keys != null) && (keys.hasNext())) {
					key = keys.next().toString();
					Log.debug("key = " + key + "\n value="
							+ parameters.get(key));
					query.setParameter(key, parameters.get(key));
				}

				pageInfo.setRecordCount(Integer.parseInt(query
						.getSingleResult().toString()));
			}

			if (parameters != null) {
				keys = parameters.keySet().iterator();
			}

			query = em.createNativeQuery(nativeSQL);
			while ((keys != null) && (keys.hasNext())) {
				key = keys.next().toString();
				Log.debug("key = " + key + "\n value=" + parameters.get(key));
				query.setParameter(key, parameters.get(key));
			}

			return this.findListObjectByQuery(query, pageInfo);

		} catch (Exception e) {
			// TODO: handle exception
			Log.error(e.getMessage());
			return null;
		}
	}
	@Override
	public List<T> findAll() {
		// TODO Auto-generated method stub
		return em.createQuery("from " + entityClass.getSimpleName())
				.getResultList();
	}

	@Override
	public List<T> findListByEJBQL(String ejbql) {
		// TODO Auto-generated method stub
		return findListByEJBQL(ejbql, null);
	}

	@Override
	public List<T> findListByEJBQL(String ejbql, Map parameters) {
		return findListByEJBQL(ejbql, null, parameters).getResultList();
		// Log.debug(ejbql);
		// Query query = null;
		// try {
		// query = em.createQuery(ejbql);
		// } catch (Exception e) {
		// e.printStackTrace();
		// }
		//
		// String key = "";
		// if ((parameters != null) && (!parameters.isEmpty())) {
		// Iterator<String> keys = parameters.keySet().iterator();
		// while ((keys != null) && (keys.hasNext())) {
		// key = keys.next().toString();
		// Log.debug("key = " + key + "\n value=" + parameters.get(key));
		// query.setParameter(key, parameters.get(key));
		// }
		// }
		// return query.getResultList();
	}

	/**
	 * 
	 * @param ejbql
	 * @param parameters
	 * @return
	 */
	public T findObjByEJBQL(String ejbql, Map parameters) {
		List<T> lst = findListByEJBQL(ejbql, parameters);
		if (lst == null || lst.isEmpty()) {
			return null;
		} else {
			return lst.get(0);
		}
	}

	public Object findNamedByObject(String sql) {
		return em.createNativeQuery(sql).getSingleResult();
	}
	/**
	 * 用来获得�?��对象�?比如Max() Sum() count() �?..
	 * 
	 * @param ejbql
	 *            查询语句
	 * @param parameters
	 *            产数
	 * @return
	 */
	public Object findByObject(String ejbql, Map parameters) {
		Log.debug(ejbql);
		Query query = null;
		try {
			query = em.createQuery(ejbql);
		} catch (Exception e) {
			e.printStackTrace();
		}

		String key = "";
		if ((parameters != null) && (!parameters.isEmpty())) {
			Iterator<String> keys = parameters.keySet().iterator();
			while ((keys != null) && (keys.hasNext())) {
				key = keys.next().toString();
				Log.debug("key = " + key + "\n value=" + parameters.get(key));
				query.setParameter(key, parameters.get(key));
			}
		}
		return query.getSingleResult();
	}

	@Override
	public PagedResults<T> findPagedAll(PageInfo pageInfo) {
		// TODO Auto-generated method stub
		return findListByEJBQL(null, pageInfo, null);
		// firstResult = firstResult < 0 ? 0 : firstResult;
		// pageSize = pageSize < 0 ? 15 : pageSize;
		// Log.debug(entityClass.getSimpleName());
		// Log.debug("firstResult is " + firstResult);
		// Log.debug("pageSize is    " + pageSize);
		// return em.createQuery("from " + entityClass.getSimpleName())
		// .setFirstResult(firstResult).setMaxResults(pageSize)
		// .getResultList();
	}

	@Override
	public int findRecordCount(String eql) {
		// TODO Auto-generated method stub
		try {
			Object o = em.createQuery(eql).getSingleResult();
			return Integer.parseInt(o.toString());
		} catch (Exception e) {
			// TODO: handle exception
			Log.error(e.getMessage());
		}
		return 0;
	}

	public Object findSingleRecord(String ejbql, Map<Object, Object> params) {
		String tmp = "";
		if ((ejbql.trim().toLowerCase().startsWith("select "))
				|| (ejbql.trim().toLowerCase().startsWith("from "))) {
			tmp = ejbql;
		} else {
			if (!ejbql.trim().toLowerCase().startsWith("where ")) {
				ejbql = " where " + ejbql;
			}
			tmp = "from " + entityClass.getSimpleName() + " " + ejbql;
		}
		try {
			Log.debug(tmp);
			Query qry = em.createQuery(tmp);
			if (params != null) {
				Iterator keys = params.keySet().iterator();
				while (keys.hasNext()) {
					String key = (String) keys.next();
					if (tmp.contains(key)) {
						qry.setParameter(key, params.get(key));
					}

				}
			}
			List list = qry.getResultList();
			if ((list == null) || (list.size() == 0)) {
				return null;
			} else {
				return list.get(0);
			}
		} catch (Exception e) {
			e.printStackTrace();
			return null;
			// TODO: handle exception
		}
	}

	protected Query createQuery(String ejbsql) {
		return em.createQuery(ejbsql);
	}

	@Override
	public int executeEJBQL(String ejbql) {
		// TODO Auto-generated method stub
		return em.createQuery(ejbql).executeUpdate();
	}
	@Override
	public int executeEJBQL(String ejbql,Map parameters) {
		return setQueryParameter(createQuery(ejbql),parameters).executeUpdate();
	}
	protected Query setQueryParameter(Query query,Map parameters){
		Iterator keys = null;
		String key = null;
		if (parameters != null) {
			keys = parameters.keySet().iterator();
		}
		while ((keys != null) && (keys.hasNext())) {
			key = keys.next().toString();
			Log.debug("key = " + key + "\n value=" + parameters.get(key));
			query.setParameter(key, parameters.get(key));
		}
		return query;
	}
	@Override
	public int executeNativeSQL(String nativeSQL) {
		// TODO Auto-generated method stub
		return em.createNativeQuery(nativeSQL).executeUpdate();
	}

	public List<T> findByOwnerid(String ownerid, boolean likeParam) {
		String sql = " from " + entityClass.getSimpleName() + " where ownerid "
				+ (likeParam ? " like ?1" : " = ?1");
		List<T> result = em.createQuery(sql).setParameter(1,
				likeParam ? ownerid + "%" : ownerid).getResultList();
		return result;
	}

	@Override
	public void moveIndex(List<T> moveList, Integer offset) {
		// TODO Auto-generated method stub

	}

	@Override
	public void redoIndex() {
		// TODO Auto-generated method stub

	}
	
	public List findPrimevalList(String ejbql, Map<Object, Object> params) {
		String tmp = "";
		if ((ejbql.trim().toLowerCase().startsWith("select "))
				|| (ejbql.trim().toLowerCase().startsWith("from "))) {
			tmp = ejbql;
		} else {
			if (!ejbql.trim().toLowerCase().startsWith("where ")) {
				ejbql = " where " + ejbql;
			}
			tmp = "from " + entityClass.getSimpleName() + " " + ejbql;
		}
		try {
			Log.debug(tmp);
			Query qry = em.createQuery(tmp);
			if (params != null) {
				Iterator keys = params.keySet().iterator();
				while (keys.hasNext()) {
					String key = (String) keys.next();
					if (tmp.contains(key)) {
						qry.setParameter(key, params.get(key));
					}

				}
			}
			return qry.getResultList();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
			// TODO: handle exception
		}
	}
}
